package com.maimao.goods.service;

import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.maimao.core.enums.ExceptionEnum;
import com.maimao.core.exception.MaiMaoDaoException;
import com.maimao.core.model.resp.PageResult;
import com.maimao.core.model.resp.Result;
import com.maimao.core.utils.PinYinUtils;
import com.maimao.goods.client.ShopClient;
import com.maimao.goods.mapper.BrandMapper;
import com.maimao.goods.mapper.CateMapper;
import com.maimao.goods.utils.JvmCacheHolder;
import com.maimao.model.goods.Brand;
import com.maimao.model.goods.Category;
import com.maimao.model.goods.input.BrandBindCateInput;
import com.maimao.model.goods.input.BrandSearchInput;
import com.maimao.model.user.input.ShopBindBrand;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author MaoLin Wang
 * @date 2020/12/8 4:42 下午
 */
@Slf4j
@Service
public class BrandService {
    @Autowired
    private BrandMapper brandMapper;

    @Autowired
    private CateService cateService;

    @Autowired
    private CateMapper cateMapper;

    @Autowired
    private ShopClient shopClient;


    @PostConstruct
    private void postConstruct() {
        onRefresh();
    }

    /**
     * 刷新品牌jvm缓存
     */
    public void onRefresh() {
        List<Brand> brands = brandMapper.selectAllValid();
        Map<Long, Brand> brandMap = brands.stream().collect(Collectors.toMap(Brand::getId, brand -> brand));
        JvmCacheHolder.brandCache.clear();
        JvmCacheHolder.brandCache.putAll(brandMap);
        log.info("JVM cache----->品牌全量数据 更新成功");
    }


    public PageResult<Brand> search(BrandSearchInput input, Integer page, Integer size) {
        PageHelper.startPage(page, size);
        List<Brand> brandList = brandMapper.selectByParam(input.getKey(), input.getHot(), input.getRecommend(), input.getStatus(), input.getOwnerId());
        return new PageResult<>(brandList);

    }

    public String selectLogoById(Integer id) {
        return brandMapper.selectLogoById(Long.valueOf(id));
    }

    @Transactional(rollbackFor = MaiMaoDaoException.class)
    public void updateLogo(int brandId, String logo) {
        brandMapper.updateLogo(logo, brandId);
    }

    /**
     * 修改基础信息
     */
    @Transactional(rollbackFor = MaiMaoDaoException.class)
    public void updateBase(Brand brand) {
        brand.setPinyin(PinYinUtils.getPinYin(brand.getName()));
        brand.setHead(PinYinUtils.getHead(brand.getName()));
        brandMapper.updateBase(brand);
    }

    /**
     * 批量更新状态
     */
    @Transactional(rollbackFor = MaiMaoDaoException.class)
    public void updateStatusBatch(Integer status, List<Integer> ids) {
        brandMapper.updateStatusBatch(status, ids);
    }

    /**
     * 加入或取消推荐
     *
     * @param id        品牌id
     * @param recommend 推荐状态
     */
    @Transactional(rollbackFor = MaiMaoDaoException.class)
    public void operRecommend(Long id, Integer recommend) {
        brandMapper.updateRecommend(id, recommend);
    }

    /**
     * 加入或取消热门
     *
     * @param id  品牌id
     * @param hot 热门状态
     */
    @Transactional(rollbackFor = MaiMaoDaoException.class)
    public void operHot(Long id, Integer hot) {
        brandMapper.updateHot(id, hot);
    }

    /**
     * TODO 暂时查询hot为1的品牌 后期需要根据数据生成热门品牌进行查询
     */
    public List<Brand> hotBrand() {

        return brandMapper.selectHot();
    }

    public List<Brand> cateBrands(Integer cid3, boolean isCompanyUser, Long userId) {
        List<Brand> brands = Lists.newArrayList();
        if (isCompanyUser) {
            //企业商家只查询自己的品牌，且必须绑定了当前分类（其实没必要，企业用户默认每个分类都查询自己的品牌即可，但弄就弄了吧）
            Brand brand = brandMapper.selectByOwnerAndCid3(userId, cid3);
            brands.add(brand);
        } else {
            brands = brandMapper.cateBrands(cid3);
        }
        return brands;
    }

    public String selectNameById(Long id) {
        return brandMapper.selectNameById(id);
    }

    public List<Brand> selectByIdBatch(List<Long> brandIds) {
        return brandMapper.selectByIdBatchSimple(brandIds);
    }

    public List<Brand> testExample() {
        return null;
    }

    public Brand selectByName(String name) {
        return brandMapper.selectByName(name);
    }

    @Transactional(rollbackFor = MaiMaoDaoException.class)
    public Long add(Brand brand) {
        brandMapper.insert(brand);

        return brand.getId();
    }

    @Transactional(rollbackFor = MaiMaoDaoException.class)
    public void checkBrand( Long id, Long shopId, Boolean success, String reason) {
        brandMapper.check(id, success ? 1 : 0, reason);
        if (success){
            Result<Void> result = shopClient.bindBrand(ShopBindBrand.builder().brandId(id).shopId(shopId).build());
            if (result==null||!result.isFlag()){
                log.error(result.getMessage());
                throw new RuntimeException("审核失败");

            }
        }
    }

    public Brand selectByOwner(Long ownerId) {
        return brandMapper.selectByOwner(ownerId);
    }

    /**
     * 查询商家注册的品牌以及品牌绑定的所有分类ID(前端分类树展示已绑定分类)
     *
     * @param shopId 店铺ID
     */
    public Map<String, Object> shopBrandCate(Long shopId) {
        Brand brand = brandMapper.selectByShopId(shopId);
        List<Integer> boundCategoryIds = null;
        if (brand != null) {
            boundCategoryIds = cateService.selectCid123ByBrandId(brand.getId());
        }
        Map<String, Object> result = Maps.newHashMapWithExpectedSize(2);
        result.put("brand", brand);
        result.put("boundCategoryIds", boundCategoryIds);
        return result;
    }

    /**
     * 给品牌绑定分类
     */
    @Transactional(rollbackFor = MaiMaoDaoException.class)
    public Result brandBindCate(BrandBindCateInput input) {
        List<Category> categories = cateService.selectBatch(input.getBindCategoryIds());
        if (ObjectUtil.isEmpty(categories) || input.getBindCategoryIds().size() != categories.size()) {
            return Result.notValid("非法分类");
        }
        List<Integer> cid3s = categories.stream().filter(category -> category.getLevel() == 3).map(Category::getId).collect(Collectors.toList());
        List<Integer> boundCids = cateMapper.selectIdsByBrandId(input.getBrandId());
        //先删除已绑定的分类
        if (ObjectUtil.isNotEmpty(boundCids)){
            brandMapper.deleteBoundCategory(input.getBrandId(), boundCids);
        }
        //添加新的分类
        brandMapper.bindCategory(input.getBrandId(), cid3s);

        return Result.ok("绑定成功");
    }

    public Brand selectByShop(Long shopId) {
        return brandMapper.selectByShopId(shopId);
    }
}
